//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2024 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif
@_spi(SotoInternal) import SotoCore

extension Ivschat {
    // MARK: Enums

    public enum ChatTokenCapability: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case deleteMessage = "DELETE_MESSAGE"
        case disconnectUser = "DISCONNECT_USER"
        case sendMessage = "SEND_MESSAGE"
        public var description: String { return self.rawValue }
    }

    public enum CreateLoggingConfigurationState: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case active = "ACTIVE"
        public var description: String { return self.rawValue }
    }

    public enum FallbackResult: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case allow = "ALLOW"
        case deny = "DENY"
        public var description: String { return self.rawValue }
    }

    public enum LoggingConfigurationState: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case active = "ACTIVE"
        case createFailed = "CREATE_FAILED"
        case creating = "CREATING"
        case deleteFailed = "DELETE_FAILED"
        case deleting = "DELETING"
        case updateFailed = "UPDATE_FAILED"
        case updating = "UPDATING"
        public var description: String { return self.rawValue }
    }

    public enum ResourceType: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case room = "ROOM"
        public var description: String { return self.rawValue }
    }

    public enum UpdateLoggingConfigurationState: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case active = "ACTIVE"
        public var description: String { return self.rawValue }
    }

    public enum ValidationExceptionReason: String, CustomStringConvertible, Codable, Sendable, CodingKeyRepresentable {
        case fieldValidationFailed = "FIELD_VALIDATION_FAILED"
        case other = "OTHER"
        case unknownOperation = "UNKNOWN_OPERATION"
        public var description: String { return self.rawValue }
    }

    public enum DestinationConfiguration: AWSEncodableShape & AWSDecodableShape, Sendable {
        /// An Amazon CloudWatch Logs destination configuration where chat activity will be logged.
        case cloudWatchLogs(CloudWatchLogsDestinationConfiguration)
        /// An Amazon Kinesis Data Firehose destination configuration where chat activity will be logged.
        case firehose(FirehoseDestinationConfiguration)
        /// An Amazon S3 destination configuration where chat activity will be logged.
        case s3(S3DestinationConfiguration)

        public init(from decoder: Decoder) throws {
            let container = try decoder.container(keyedBy: CodingKeys.self)
            guard container.allKeys.count == 1, let key = container.allKeys.first else {
                let context = DecodingError.Context(
                    codingPath: container.codingPath,
                    debugDescription: "Expected exactly one key, but got \(container.allKeys.count)"
                )
                throw DecodingError.dataCorrupted(context)
            }
            switch key {
            case .cloudWatchLogs:
                let value = try container.decode(CloudWatchLogsDestinationConfiguration.self, forKey: .cloudWatchLogs)
                self = .cloudWatchLogs(value)
            case .firehose:
                let value = try container.decode(FirehoseDestinationConfiguration.self, forKey: .firehose)
                self = .firehose(value)
            case .s3:
                let value = try container.decode(S3DestinationConfiguration.self, forKey: .s3)
                self = .s3(value)
            }
        }

        public func encode(to encoder: Encoder) throws {
            var container = encoder.container(keyedBy: CodingKeys.self)
            switch self {
            case .cloudWatchLogs(let value):
                try container.encode(value, forKey: .cloudWatchLogs)
            case .firehose(let value):
                try container.encode(value, forKey: .firehose)
            case .s3(let value):
                try container.encode(value, forKey: .s3)
            }
        }

        public func validate(name: String) throws {
            switch self {
            case .cloudWatchLogs(let value):
                try value.validate(name: "\(name).cloudWatchLogs")
            case .firehose(let value):
                try value.validate(name: "\(name).firehose")
            case .s3(let value):
                try value.validate(name: "\(name).s3")
            }
        }

        private enum CodingKeys: String, CodingKey {
            case cloudWatchLogs = "cloudWatchLogs"
            case firehose = "firehose"
            case s3 = "s3"
        }
    }

    // MARK: Shapes

    public struct CloudWatchLogsDestinationConfiguration: AWSEncodableShape & AWSDecodableShape {
        /// Name of the Amazon Cloudwatch Logs destination where chat activity will be logged.
        public let logGroupName: String

        @inlinable
        public init(logGroupName: String) {
            self.logGroupName = logGroupName
        }

        public func validate(name: String) throws {
            try self.validate(self.logGroupName, name: "logGroupName", parent: name, max: 512)
            try self.validate(self.logGroupName, name: "logGroupName", parent: name, min: 1)
            try self.validate(self.logGroupName, name: "logGroupName", parent: name, pattern: "^[\\.\\-_/#A-Za-z0-9]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case logGroupName = "logGroupName"
        }
    }

    public struct ConflictException: AWSErrorShape {
        public let message: String
        public let resourceId: String
        public let resourceType: ResourceType

        @inlinable
        public init(message: String, resourceId: String, resourceType: ResourceType) {
            self.message = message
            self.resourceId = resourceId
            self.resourceType = resourceType
        }

        private enum CodingKeys: String, CodingKey {
            case message = "message"
            case resourceId = "resourceId"
            case resourceType = "resourceType"
        }
    }

    public struct CreateChatTokenRequest: AWSEncodableShape {
        /// Application-provided attributes to encode into the token and attach to a chat session. Map keys and values can contain UTF-8 encoded text. The maximum length of this field is 1 KB total.
        public let attributes: [String: String]?
        /// Set of capabilities that the user is allowed to perform in the room. Default: None (the capability to view messages is implicitly included in all requests).
        public let capabilities: [ChatTokenCapability]?
        /// Identifier of the room that the client is trying to access. Currently this must be an ARN.
        public let roomIdentifier: String
        /// Session duration (in minutes), after which the session expires. Default: 60 (1 hour).
        public let sessionDurationInMinutes: Int?
        /// Application-provided ID that uniquely identifies the user associated with this token. This can be any UTF-8 encoded text.
        public let userId: String

        @inlinable
        public init(attributes: [String: String]? = nil, capabilities: [ChatTokenCapability]? = nil, roomIdentifier: String, sessionDurationInMinutes: Int? = nil, userId: String) {
            self.attributes = attributes
            self.capabilities = capabilities
            self.roomIdentifier = roomIdentifier
            self.sessionDurationInMinutes = sessionDurationInMinutes
            self.userId = userId
        }

        public func validate(name: String) throws {
            try self.validate(self.roomIdentifier, name: "roomIdentifier", parent: name, max: 128)
            try self.validate(self.roomIdentifier, name: "roomIdentifier", parent: name, min: 1)
            try self.validate(self.roomIdentifier, name: "roomIdentifier", parent: name, pattern: "^arn:aws:ivschat:[a-z0-9-]+:[0-9]+:room/[a-zA-Z0-9-]+$")
            try self.validate(self.sessionDurationInMinutes, name: "sessionDurationInMinutes", parent: name, max: 180)
            try self.validate(self.sessionDurationInMinutes, name: "sessionDurationInMinutes", parent: name, min: 1)
            try self.validate(self.userId, name: "userId", parent: name, max: 128)
            try self.validate(self.userId, name: "userId", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case attributes = "attributes"
            case capabilities = "capabilities"
            case roomIdentifier = "roomIdentifier"
            case sessionDurationInMinutes = "sessionDurationInMinutes"
            case userId = "userId"
        }
    }

    public struct CreateChatTokenResponse: AWSDecodableShape {
        /// Time after which an end user's session is no longer valid. This is an ISO 8601 timestamp; note that this is returned as a string.
        @OptionalCustomCoding<ISO8601DateCoder>
        public var sessionExpirationTime: Date?
        /// The issued client token, encrypted.
        public let token: String?
        /// Time after which the token is no longer valid and cannot be used to connect to a room. This is an ISO 8601 timestamp; note that this is returned as a string.
        @OptionalCustomCoding<ISO8601DateCoder>
        public var tokenExpirationTime: Date?

        @inlinable
        public init(sessionExpirationTime: Date? = nil, token: String? = nil, tokenExpirationTime: Date? = nil) {
            self.sessionExpirationTime = sessionExpirationTime
            self.token = token
            self.tokenExpirationTime = tokenExpirationTime
        }

        private enum CodingKeys: String, CodingKey {
            case sessionExpirationTime = "sessionExpirationTime"
            case token = "token"
            case tokenExpirationTime = "tokenExpirationTime"
        }
    }

    public struct CreateLoggingConfigurationRequest: AWSEncodableShape {
        /// A complex type that contains a destination configuration for where chat content will be logged. There can be only one type of destination (cloudWatchLogs, firehose, or s3) in a destinationConfiguration.
        public let destinationConfiguration: DestinationConfiguration
        /// Logging-configuration name. The value does not need to be unique.
        public let name: String?
        /// Tags to attach to the resource. Array of maps, each of the form string:string (key:value). See Best practices and strategies in Tagging Amazon Web Services Resources and Tag Editor for details, including restrictions that apply to tags and "Tag naming limits and requirements"; Amazon IVS Chat has no constraints on tags beyond what is documented there.
        public let tags: [String: String]?

        @inlinable
        public init(destinationConfiguration: DestinationConfiguration, name: String? = nil, tags: [String: String]? = nil) {
            self.destinationConfiguration = destinationConfiguration
            self.name = name
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.destinationConfiguration.validate(name: "\(name).destinationConfiguration")
            try self.validate(self.name, name: "name", parent: name, max: 128)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[a-zA-Z0-9-_]*$")
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 50)
        }

        private enum CodingKeys: String, CodingKey {
            case destinationConfiguration = "destinationConfiguration"
            case name = "name"
            case tags = "tags"
        }
    }

    public struct CreateLoggingConfigurationResponse: AWSDecodableShape {
        /// Logging-configuration ARN, assigned by the system.
        public let arn: String?
        /// Time when the logging configuration was created. This is an ISO 8601 timestamp; note that this is returned as a string.
        @OptionalCustomCoding<ISO8601DateCoder>
        public var createTime: Date?
        /// A complex type that contains a destination configuration for where chat content will be logged, from the request. There is only one type of destination (cloudWatchLogs, firehose, or s3) in a destinationConfiguration.
        public let destinationConfiguration: DestinationConfiguration?
        /// Logging-configuration ID, generated by the system. This is a relative identifier, the part of the ARN that uniquely identifies the logging configuration.
        public let id: String?
        /// Logging-configuration name, from the request (if specified).
        public let name: String?
        /// The state of the logging configuration. When the state is ACTIVE, the configuration is ready to log chat content.
        public let state: CreateLoggingConfigurationState?
        /// Tags attached to the resource, from the request (if specified). Array of maps, each of the form string:string (key:value).
        public let tags: [String: String]?
        /// Time of the logging configuration’s last update. This is an ISO 8601 timestamp; note that this is returned as a string.
        @OptionalCustomCoding<ISO8601DateCoder>
        public var updateTime: Date?

        @inlinable
        public init(arn: String? = nil, createTime: Date? = nil, destinationConfiguration: DestinationConfiguration? = nil, id: String? = nil, name: String? = nil, state: CreateLoggingConfigurationState? = nil, tags: [String: String]? = nil, updateTime: Date? = nil) {
            self.arn = arn
            self.createTime = createTime
            self.destinationConfiguration = destinationConfiguration
            self.id = id
            self.name = name
            self.state = state
            self.tags = tags
            self.updateTime = updateTime
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case createTime = "createTime"
            case destinationConfiguration = "destinationConfiguration"
            case id = "id"
            case name = "name"
            case state = "state"
            case tags = "tags"
            case updateTime = "updateTime"
        }
    }

    public struct CreateRoomRequest: AWSEncodableShape {
        /// Array of logging-configuration identifiers attached to the room.
        public let loggingConfigurationIdentifiers: [String]?
        /// Maximum number of characters in a single message. Messages are expected to be UTF-8 encoded and this limit applies specifically to rune/code-point count, not number of bytes. Default: 500.
        public let maximumMessageLength: Int?
        /// Maximum number of messages per second that can be sent to the room (by all clients). Default: 10.
        public let maximumMessageRatePerSecond: Int?
        /// Configuration information for optional review of messages.
        public let messageReviewHandler: MessageReviewHandler?
        /// Room name. The value does not need to be unique.
        public let name: String?
        /// Tags to attach to the resource. Array of maps, each of the form string:string (key:value). See Best practices and strategies in Tagging Amazon Web Services Resources and Tag Editor for details, including restrictions that apply to tags and "Tag naming limits and requirements"; Amazon IVS Chat has no constraints beyond what is documented there.
        public let tags: [String: String]?

        @inlinable
        public init(loggingConfigurationIdentifiers: [String]? = nil, maximumMessageLength: Int? = nil, maximumMessageRatePerSecond: Int? = nil, messageReviewHandler: MessageReviewHandler? = nil, name: String? = nil, tags: [String: String]? = nil) {
            self.loggingConfigurationIdentifiers = loggingConfigurationIdentifiers
            self.maximumMessageLength = maximumMessageLength
            self.maximumMessageRatePerSecond = maximumMessageRatePerSecond
            self.messageReviewHandler = messageReviewHandler
            self.name = name
            self.tags = tags
        }

        public func validate(name: String) throws {
            try self.loggingConfigurationIdentifiers?.forEach {
                try validate($0, name: "loggingConfigurationIdentifiers[]", parent: name, max: 128)
                try validate($0, name: "loggingConfigurationIdentifiers[]", parent: name, min: 1)
                try validate($0, name: "loggingConfigurationIdentifiers[]", parent: name, pattern: "^arn:aws:ivschat:[a-z0-9-]+:[0-9]+:logging-configuration/[a-zA-Z0-9-]+$")
            }
            try self.validate(self.loggingConfigurationIdentifiers, name: "loggingConfigurationIdentifiers", parent: name, max: 3)
            try self.validate(self.maximumMessageLength, name: "maximumMessageLength", parent: name, max: 500)
            try self.validate(self.maximumMessageLength, name: "maximumMessageLength", parent: name, min: 1)
            try self.validate(self.maximumMessageRatePerSecond, name: "maximumMessageRatePerSecond", parent: name, max: 100)
            try self.validate(self.maximumMessageRatePerSecond, name: "maximumMessageRatePerSecond", parent: name, min: 1)
            try self.messageReviewHandler?.validate(name: "\(name).messageReviewHandler")
            try self.validate(self.name, name: "name", parent: name, max: 128)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[a-zA-Z0-9-_]*$")
            try self.tags?.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 50)
        }

        private enum CodingKeys: String, CodingKey {
            case loggingConfigurationIdentifiers = "loggingConfigurationIdentifiers"
            case maximumMessageLength = "maximumMessageLength"
            case maximumMessageRatePerSecond = "maximumMessageRatePerSecond"
            case messageReviewHandler = "messageReviewHandler"
            case name = "name"
            case tags = "tags"
        }
    }

    public struct CreateRoomResponse: AWSDecodableShape {
        /// Room ARN, assigned by the system.
        public let arn: String?
        /// Time when the room was created. This is an ISO 8601 timestamp; note that this is returned as a string.
        @OptionalCustomCoding<ISO8601DateCoder>
        public var createTime: Date?
        /// Room ID, generated by the system. This is a relative identifier, the part of the ARN that uniquely identifies the room.
        public let id: String?
        /// Array of logging configurations attached to the room, from the request (if specified).
        public let loggingConfigurationIdentifiers: [String]?
        /// Maximum number of characters in a single message, from the request (if specified).
        public let maximumMessageLength: Int?
        /// Maximum number of messages per second that can be sent to the room (by all clients), from the request (if specified).
        public let maximumMessageRatePerSecond: Int?
        /// Configuration information for optional review of messages.
        public let messageReviewHandler: MessageReviewHandler?
        /// Room name, from the request (if specified).
        public let name: String?
        /// Tags attached to the resource, from the request (if specified).
        public let tags: [String: String]?
        /// Time of the room’s last update. This is an ISO 8601 timestamp; note that this is returned as a string.
        @OptionalCustomCoding<ISO8601DateCoder>
        public var updateTime: Date?

        @inlinable
        public init(arn: String? = nil, createTime: Date? = nil, id: String? = nil, loggingConfigurationIdentifiers: [String]? = nil, maximumMessageLength: Int? = nil, maximumMessageRatePerSecond: Int? = nil, messageReviewHandler: MessageReviewHandler? = nil, name: String? = nil, tags: [String: String]? = nil, updateTime: Date? = nil) {
            self.arn = arn
            self.createTime = createTime
            self.id = id
            self.loggingConfigurationIdentifiers = loggingConfigurationIdentifiers
            self.maximumMessageLength = maximumMessageLength
            self.maximumMessageRatePerSecond = maximumMessageRatePerSecond
            self.messageReviewHandler = messageReviewHandler
            self.name = name
            self.tags = tags
            self.updateTime = updateTime
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case createTime = "createTime"
            case id = "id"
            case loggingConfigurationIdentifiers = "loggingConfigurationIdentifiers"
            case maximumMessageLength = "maximumMessageLength"
            case maximumMessageRatePerSecond = "maximumMessageRatePerSecond"
            case messageReviewHandler = "messageReviewHandler"
            case name = "name"
            case tags = "tags"
            case updateTime = "updateTime"
        }
    }

    public struct DeleteLoggingConfigurationRequest: AWSEncodableShape {
        /// Identifier of the logging configuration to be deleted.
        public let identifier: String

        @inlinable
        public init(identifier: String) {
            self.identifier = identifier
        }

        public func validate(name: String) throws {
            try self.validate(self.identifier, name: "identifier", parent: name, max: 128)
            try self.validate(self.identifier, name: "identifier", parent: name, min: 1)
            try self.validate(self.identifier, name: "identifier", parent: name, pattern: "^arn:aws:ivschat:[a-z0-9-]+:[0-9]+:logging-configuration/[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case identifier = "identifier"
        }
    }

    public struct DeleteMessageRequest: AWSEncodableShape {
        /// ID of the message to be deleted. This is the Id field in the received message (see  Message (Subscribe) in the Chat Messaging API).
        public let id: String
        /// Reason for deleting the message.
        public let reason: String?
        /// Identifier of the room where the message should be deleted. Currently this must be an ARN.
        public let roomIdentifier: String

        @inlinable
        public init(id: String, reason: String? = nil, roomIdentifier: String) {
            self.id = id
            self.reason = reason
            self.roomIdentifier = roomIdentifier
        }

        public func validate(name: String) throws {
            try self.validate(self.id, name: "id", parent: name, max: 12)
            try self.validate(self.id, name: "id", parent: name, min: 12)
            try self.validate(self.id, name: "id", parent: name, pattern: "^[a-zA-Z0-9]+$")
            try self.validate(self.reason, name: "reason", parent: name, max: 256)
            try self.validate(self.reason, name: "reason", parent: name, min: 1)
            try self.validate(self.roomIdentifier, name: "roomIdentifier", parent: name, max: 128)
            try self.validate(self.roomIdentifier, name: "roomIdentifier", parent: name, min: 1)
            try self.validate(self.roomIdentifier, name: "roomIdentifier", parent: name, pattern: "^arn:aws:ivschat:[a-z0-9-]+:[0-9]+:room/[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case id = "id"
            case reason = "reason"
            case roomIdentifier = "roomIdentifier"
        }
    }

    public struct DeleteMessageResponse: AWSDecodableShape {
        /// Operation identifier, generated by Amazon IVS Chat.
        public let id: String?

        @inlinable
        public init(id: String? = nil) {
            self.id = id
        }

        private enum CodingKeys: String, CodingKey {
            case id = "id"
        }
    }

    public struct DeleteRoomRequest: AWSEncodableShape {
        /// Identifier of the room to be deleted. Currently this must be an ARN.
        public let identifier: String

        @inlinable
        public init(identifier: String) {
            self.identifier = identifier
        }

        public func validate(name: String) throws {
            try self.validate(self.identifier, name: "identifier", parent: name, max: 128)
            try self.validate(self.identifier, name: "identifier", parent: name, min: 1)
            try self.validate(self.identifier, name: "identifier", parent: name, pattern: "^arn:aws:ivschat:[a-z0-9-]+:[0-9]+:room/[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case identifier = "identifier"
        }
    }

    public struct DisconnectUserRequest: AWSEncodableShape {
        /// Reason for disconnecting the user.
        public let reason: String?
        /// Identifier of the room from which the user's clients should be disconnected. Currently this must be an ARN.
        public let roomIdentifier: String
        /// ID of the user (connection) to disconnect from the room.
        public let userId: String

        @inlinable
        public init(reason: String? = nil, roomIdentifier: String, userId: String) {
            self.reason = reason
            self.roomIdentifier = roomIdentifier
            self.userId = userId
        }

        public func validate(name: String) throws {
            try self.validate(self.reason, name: "reason", parent: name, max: 256)
            try self.validate(self.reason, name: "reason", parent: name, min: 1)
            try self.validate(self.roomIdentifier, name: "roomIdentifier", parent: name, max: 128)
            try self.validate(self.roomIdentifier, name: "roomIdentifier", parent: name, min: 1)
            try self.validate(self.roomIdentifier, name: "roomIdentifier", parent: name, pattern: "^arn:aws:ivschat:[a-z0-9-]+:[0-9]+:room/[a-zA-Z0-9-]+$")
            try self.validate(self.userId, name: "userId", parent: name, max: 128)
            try self.validate(self.userId, name: "userId", parent: name, min: 1)
        }

        private enum CodingKeys: String, CodingKey {
            case reason = "reason"
            case roomIdentifier = "roomIdentifier"
            case userId = "userId"
        }
    }

    public struct DisconnectUserResponse: AWSDecodableShape {
        public init() {}
    }

    public struct FirehoseDestinationConfiguration: AWSEncodableShape & AWSDecodableShape {
        /// Name of the Amazon Kinesis Firehose delivery stream where chat activity will be logged.
        public let deliveryStreamName: String

        @inlinable
        public init(deliveryStreamName: String) {
            self.deliveryStreamName = deliveryStreamName
        }

        public func validate(name: String) throws {
            try self.validate(self.deliveryStreamName, name: "deliveryStreamName", parent: name, max: 64)
            try self.validate(self.deliveryStreamName, name: "deliveryStreamName", parent: name, min: 1)
            try self.validate(self.deliveryStreamName, name: "deliveryStreamName", parent: name, pattern: "^[a-zA-Z0-9_.-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case deliveryStreamName = "deliveryStreamName"
        }
    }

    public struct GetLoggingConfigurationRequest: AWSEncodableShape {
        /// Identifier of the logging configuration to be retrieved.
        public let identifier: String

        @inlinable
        public init(identifier: String) {
            self.identifier = identifier
        }

        public func validate(name: String) throws {
            try self.validate(self.identifier, name: "identifier", parent: name, max: 128)
            try self.validate(self.identifier, name: "identifier", parent: name, min: 1)
            try self.validate(self.identifier, name: "identifier", parent: name, pattern: "^arn:aws:ivschat:[a-z0-9-]+:[0-9]+:logging-configuration/[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case identifier = "identifier"
        }
    }

    public struct GetLoggingConfigurationResponse: AWSDecodableShape {
        /// Logging-configuration ARN, from the request (if identifier was an ARN).
        public let arn: String?
        /// Time when the logging configuration was created. This is an ISO 8601 timestamp; note that this is returned as a string.
        @OptionalCustomCoding<ISO8601DateCoder>
        public var createTime: Date?
        /// A complex type that contains a destination configuration for where chat content will be logged. There is only one type of destination (cloudWatchLogs, firehose, or s3) in a destinationConfiguration.
        public let destinationConfiguration: DestinationConfiguration?
        /// Logging-configuration ID, generated by the system. This is a relative identifier, the part of the ARN that uniquely identifies the logging configuration.
        public let id: String?
        /// Logging-configuration name. This value does not need to be unique.
        public let name: String?
        /// The state of the logging configuration. When the state is ACTIVE, the configuration is ready to log chat content.
        public let state: LoggingConfigurationState?
        /// Tags attached to the resource. Array of maps, each of the form string:string (key:value).
        public let tags: [String: String]?
        /// Time of the logging configuration’s last update. This is an ISO 8601 timestamp; note that this is returned as a string.
        @OptionalCustomCoding<ISO8601DateCoder>
        public var updateTime: Date?

        @inlinable
        public init(arn: String? = nil, createTime: Date? = nil, destinationConfiguration: DestinationConfiguration? = nil, id: String? = nil, name: String? = nil, state: LoggingConfigurationState? = nil, tags: [String: String]? = nil, updateTime: Date? = nil) {
            self.arn = arn
            self.createTime = createTime
            self.destinationConfiguration = destinationConfiguration
            self.id = id
            self.name = name
            self.state = state
            self.tags = tags
            self.updateTime = updateTime
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case createTime = "createTime"
            case destinationConfiguration = "destinationConfiguration"
            case id = "id"
            case name = "name"
            case state = "state"
            case tags = "tags"
            case updateTime = "updateTime"
        }
    }

    public struct GetRoomRequest: AWSEncodableShape {
        /// Identifier of the room for which the configuration is to be retrieved. Currently this must be an ARN.
        public let identifier: String

        @inlinable
        public init(identifier: String) {
            self.identifier = identifier
        }

        public func validate(name: String) throws {
            try self.validate(self.identifier, name: "identifier", parent: name, max: 128)
            try self.validate(self.identifier, name: "identifier", parent: name, min: 1)
            try self.validate(self.identifier, name: "identifier", parent: name, pattern: "^arn:aws:ivschat:[a-z0-9-]+:[0-9]+:room/[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case identifier = "identifier"
        }
    }

    public struct GetRoomResponse: AWSDecodableShape {
        /// Room ARN, from the request (if identifier was an ARN).
        public let arn: String?
        /// Time when the room was created. This is an ISO 8601 timestamp; note that this is returned as a string.
        @OptionalCustomCoding<ISO8601DateCoder>
        public var createTime: Date?
        /// Room ID, generated by the system. This is a relative identifier, the part of the ARN that uniquely identifies the room.
        public let id: String?
        /// Array of logging configurations attached to the room.
        public let loggingConfigurationIdentifiers: [String]?
        /// Maximum number of characters in a single message. Messages are expected to be UTF-8 encoded and this limit applies specifically to rune/code-point count, not number of bytes. Default: 500.
        public let maximumMessageLength: Int?
        /// Maximum number of messages per second that can be sent to the room (by all clients). Default: 10.
        public let maximumMessageRatePerSecond: Int?
        /// Configuration information for optional review of messages.
        public let messageReviewHandler: MessageReviewHandler?
        /// Room name. The value does not need to be unique.
        public let name: String?
        /// Tags attached to the resource. Array of maps, each of the form string:string (key:value).
        public let tags: [String: String]?
        /// Time of the room’s last update. This is an ISO 8601 timestamp; note that this is returned as a string.
        @OptionalCustomCoding<ISO8601DateCoder>
        public var updateTime: Date?

        @inlinable
        public init(arn: String? = nil, createTime: Date? = nil, id: String? = nil, loggingConfigurationIdentifiers: [String]? = nil, maximumMessageLength: Int? = nil, maximumMessageRatePerSecond: Int? = nil, messageReviewHandler: MessageReviewHandler? = nil, name: String? = nil, tags: [String: String]? = nil, updateTime: Date? = nil) {
            self.arn = arn
            self.createTime = createTime
            self.id = id
            self.loggingConfigurationIdentifiers = loggingConfigurationIdentifiers
            self.maximumMessageLength = maximumMessageLength
            self.maximumMessageRatePerSecond = maximumMessageRatePerSecond
            self.messageReviewHandler = messageReviewHandler
            self.name = name
            self.tags = tags
            self.updateTime = updateTime
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case createTime = "createTime"
            case id = "id"
            case loggingConfigurationIdentifiers = "loggingConfigurationIdentifiers"
            case maximumMessageLength = "maximumMessageLength"
            case maximumMessageRatePerSecond = "maximumMessageRatePerSecond"
            case messageReviewHandler = "messageReviewHandler"
            case name = "name"
            case tags = "tags"
            case updateTime = "updateTime"
        }
    }

    public struct ListLoggingConfigurationsRequest: AWSEncodableShape {
        /// Maximum number of logging configurations to return. Default: 50.
        public let maxResults: Int?
        /// The first logging configurations to retrieve. This is used for pagination; see the nextToken response field.
        public let nextToken: String?

        @inlinable
        public init(maxResults: Int? = nil, nextToken: String? = nil) {
            self.maxResults = maxResults
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 50)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 1024)
        }

        private enum CodingKeys: String, CodingKey {
            case maxResults = "maxResults"
            case nextToken = "nextToken"
        }
    }

    public struct ListLoggingConfigurationsResponse: AWSDecodableShape {
        /// List of the matching logging configurations (summary information only). There is only one type of destination (cloudWatchLogs, firehose, or s3) in a destinationConfiguration.
        public let loggingConfigurations: [LoggingConfigurationSummary]
        /// If there are more logging configurations than maxResults, use nextToken in the request to get the next set.
        public let nextToken: String?

        @inlinable
        public init(loggingConfigurations: [LoggingConfigurationSummary], nextToken: String? = nil) {
            self.loggingConfigurations = loggingConfigurations
            self.nextToken = nextToken
        }

        private enum CodingKeys: String, CodingKey {
            case loggingConfigurations = "loggingConfigurations"
            case nextToken = "nextToken"
        }
    }

    public struct ListRoomsRequest: AWSEncodableShape {
        /// Logging-configuration identifier.
        public let loggingConfigurationIdentifier: String?
        /// Maximum number of rooms to return. Default: 50.
        public let maxResults: Int?
        /// Filters the list to match the specified message review handler URI.
        public let messageReviewHandlerUri: String?
        /// Filters the list to match the specified room name.
        public let name: String?
        /// The first room to retrieve. This is used for pagination; see the nextToken response field.
        public let nextToken: String?

        @inlinable
        public init(loggingConfigurationIdentifier: String? = nil, maxResults: Int? = nil, messageReviewHandlerUri: String? = nil, name: String? = nil, nextToken: String? = nil) {
            self.loggingConfigurationIdentifier = loggingConfigurationIdentifier
            self.maxResults = maxResults
            self.messageReviewHandlerUri = messageReviewHandlerUri
            self.name = name
            self.nextToken = nextToken
        }

        public func validate(name: String) throws {
            try self.validate(self.loggingConfigurationIdentifier, name: "loggingConfigurationIdentifier", parent: name, max: 128)
            try self.validate(self.loggingConfigurationIdentifier, name: "loggingConfigurationIdentifier", parent: name, min: 1)
            try self.validate(self.loggingConfigurationIdentifier, name: "loggingConfigurationIdentifier", parent: name, pattern: "^arn:aws:ivschat:[a-z0-9-]+:[0-9]+:logging-configuration/[a-zA-Z0-9-]+$")
            try self.validate(self.maxResults, name: "maxResults", parent: name, max: 50)
            try self.validate(self.maxResults, name: "maxResults", parent: name, min: 1)
            try self.validate(self.messageReviewHandlerUri, name: "messageReviewHandlerUri", parent: name, max: 170)
            try self.validate(self.messageReviewHandlerUri, name: "messageReviewHandlerUri", parent: name, pattern: "^$|^arn:aws:lambda:[a-z0-9-]+:[0-9]{12}:function:.+")
            try self.validate(self.name, name: "name", parent: name, max: 128)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[a-zA-Z0-9-_]*$")
            try self.validate(self.nextToken, name: "nextToken", parent: name, max: 1024)
        }

        private enum CodingKeys: String, CodingKey {
            case loggingConfigurationIdentifier = "loggingConfigurationIdentifier"
            case maxResults = "maxResults"
            case messageReviewHandlerUri = "messageReviewHandlerUri"
            case name = "name"
            case nextToken = "nextToken"
        }
    }

    public struct ListRoomsResponse: AWSDecodableShape {
        /// If there are more rooms than maxResults, use nextToken in the request to get the next set.
        public let nextToken: String?
        /// List of the matching rooms (summary information only).
        public let rooms: [RoomSummary]

        @inlinable
        public init(nextToken: String? = nil, rooms: [RoomSummary]) {
            self.nextToken = nextToken
            self.rooms = rooms
        }

        private enum CodingKeys: String, CodingKey {
            case nextToken = "nextToken"
            case rooms = "rooms"
        }
    }

    public struct ListTagsForResourceRequest: AWSEncodableShape {
        /// The ARN of the resource to be retrieved. The ARN must be URL-encoded.
        public let resourceArn: String

        @inlinable
        public init(resourceArn: String) {
            self.resourceArn = resourceArn
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.resourceArn, key: "resourceArn")
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 128)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws:ivschat:[a-z0-9-]+:[0-9]+:[a-z-]/[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct ListTagsForResourceResponse: AWSDecodableShape {
        /// Tags attached to the resource. Array of maps, each of the form string:string (key:value).
        public let tags: [String: String]

        @inlinable
        public init(tags: [String: String]) {
            self.tags = tags
        }

        private enum CodingKeys: String, CodingKey {
            case tags = "tags"
        }
    }

    public struct LoggingConfigurationSummary: AWSDecodableShape {
        /// Logging-configuration ARN.
        public let arn: String?
        /// Time when the logging configuration was created. This is an ISO 8601 timestamp; note that this is returned as a string.
        @OptionalCustomCoding<ISO8601DateCoder>
        public var createTime: Date?
        /// A complex type that contains a destination configuration for where chat content will be logged.
        public let destinationConfiguration: DestinationConfiguration?
        /// Logging-configuration ID, generated by the system. This is a relative identifier, the part of the ARN that uniquely identifies the room.
        public let id: String?
        /// Logging-configuration name. The value does not need to be unique.
        public let name: String?
        /// The state of the logging configuration. When this is ACTIVE, the configuration is ready for logging chat content.
        public let state: LoggingConfigurationState?
        /// Tags to attach to the resource. Array of maps, each of the form string:string (key:value). See Best practices and strategies in Tagging Amazon Web Services Resources and Tag Editor for details, including restrictions that apply to tags and "Tag naming limits and requirements"; Amazon IVS Chat has no constraints on tags beyond what is documented there.
        public let tags: [String: String]?
        /// Time of the logging configuration’s last update. This is an ISO 8601 timestamp; note that this is returned as a string.
        @OptionalCustomCoding<ISO8601DateCoder>
        public var updateTime: Date?

        @inlinable
        public init(arn: String? = nil, createTime: Date? = nil, destinationConfiguration: DestinationConfiguration? = nil, id: String? = nil, name: String? = nil, state: LoggingConfigurationState? = nil, tags: [String: String]? = nil, updateTime: Date? = nil) {
            self.arn = arn
            self.createTime = createTime
            self.destinationConfiguration = destinationConfiguration
            self.id = id
            self.name = name
            self.state = state
            self.tags = tags
            self.updateTime = updateTime
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case createTime = "createTime"
            case destinationConfiguration = "destinationConfiguration"
            case id = "id"
            case name = "name"
            case state = "state"
            case tags = "tags"
            case updateTime = "updateTime"
        }
    }

    public struct MessageReviewHandler: AWSEncodableShape & AWSDecodableShape {
        /// Specifies the fallback behavior (whether the message is allowed or denied) if the handler does not return a valid response, encounters an error, or times out. (For the timeout period, see  Service Quotas.) If allowed, the message is delivered with returned content to all users connected to the room. If denied, the message is not delivered to any user. Default: ALLOW.
        public let fallbackResult: FallbackResult?
        /// Identifier of the message review handler. Currently this must be an ARN of a lambda function.
        public let uri: String?

        @inlinable
        public init(fallbackResult: FallbackResult? = nil, uri: String? = nil) {
            self.fallbackResult = fallbackResult
            self.uri = uri
        }

        public func validate(name: String) throws {
            try self.validate(self.uri, name: "uri", parent: name, max: 170)
            try self.validate(self.uri, name: "uri", parent: name, pattern: "^$|^arn:aws:lambda:[a-z0-9-]+:[0-9]{12}:function:.+")
        }

        private enum CodingKeys: String, CodingKey {
            case fallbackResult = "fallbackResult"
            case uri = "uri"
        }
    }

    public struct ResourceNotFoundException: AWSErrorShape {
        public let message: String
        public let resourceId: String
        public let resourceType: ResourceType

        @inlinable
        public init(message: String, resourceId: String, resourceType: ResourceType) {
            self.message = message
            self.resourceId = resourceId
            self.resourceType = resourceType
        }

        private enum CodingKeys: String, CodingKey {
            case message = "message"
            case resourceId = "resourceId"
            case resourceType = "resourceType"
        }
    }

    public struct RoomSummary: AWSDecodableShape {
        /// Room ARN.
        public let arn: String?
        /// Time when the room was created. This is an ISO 8601 timestamp; note that this is returned as a string.
        @OptionalCustomCoding<ISO8601DateCoder>
        public var createTime: Date?
        /// Room ID, generated by the system. This is a relative identifier, the part of the ARN that uniquely identifies the room.
        public let id: String?
        /// List of logging-configuration identifiers attached to the room.
        public let loggingConfigurationIdentifiers: [String]?
        /// Configuration information for optional review of messages.
        public let messageReviewHandler: MessageReviewHandler?
        /// Room name. The value does not need to be unique.
        public let name: String?
        /// Tags attached to the resource. Array of maps, each of the form string:string (key:value). See Best practices and strategies in Tagging Amazon Web Services Resources and Tag Editor for details, including restrictions that apply to tags and "Tag naming limits and requirements"; Amazon IVS Chat has no constraints beyond what is documented there.
        public let tags: [String: String]?
        /// Time of the room’s last update. This is an ISO 8601 timestamp; note that this is returned as a string.
        @OptionalCustomCoding<ISO8601DateCoder>
        public var updateTime: Date?

        @inlinable
        public init(arn: String? = nil, createTime: Date? = nil, id: String? = nil, loggingConfigurationIdentifiers: [String]? = nil, messageReviewHandler: MessageReviewHandler? = nil, name: String? = nil, tags: [String: String]? = nil, updateTime: Date? = nil) {
            self.arn = arn
            self.createTime = createTime
            self.id = id
            self.loggingConfigurationIdentifiers = loggingConfigurationIdentifiers
            self.messageReviewHandler = messageReviewHandler
            self.name = name
            self.tags = tags
            self.updateTime = updateTime
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case createTime = "createTime"
            case id = "id"
            case loggingConfigurationIdentifiers = "loggingConfigurationIdentifiers"
            case messageReviewHandler = "messageReviewHandler"
            case name = "name"
            case tags = "tags"
            case updateTime = "updateTime"
        }
    }

    public struct S3DestinationConfiguration: AWSEncodableShape & AWSDecodableShape {
        /// Name of the Amazon S3 bucket where chat activity will be logged.
        public let bucketName: String

        @inlinable
        public init(bucketName: String) {
            self.bucketName = bucketName
        }

        public func validate(name: String) throws {
            try self.validate(self.bucketName, name: "bucketName", parent: name, max: 63)
            try self.validate(self.bucketName, name: "bucketName", parent: name, min: 3)
            try self.validate(self.bucketName, name: "bucketName", parent: name, pattern: "^[a-z0-9-.]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case bucketName = "bucketName"
        }
    }

    public struct SendEventRequest: AWSEncodableShape {
        /// Application-defined metadata to attach to the event sent to clients. The maximum length of the metadata is 1 KB total.
        public let attributes: [String: String]?
        /// Application-defined name of the event to send to clients.
        public let eventName: String
        /// Identifier of the room to which the event will be sent. Currently this must be an ARN.
        public let roomIdentifier: String

        @inlinable
        public init(attributes: [String: String]? = nil, eventName: String, roomIdentifier: String) {
            self.attributes = attributes
            self.eventName = eventName
            self.roomIdentifier = roomIdentifier
        }

        public func validate(name: String) throws {
            try self.validate(self.eventName, name: "eventName", parent: name, max: 100)
            try self.validate(self.eventName, name: "eventName", parent: name, min: 1)
            try self.validate(self.roomIdentifier, name: "roomIdentifier", parent: name, max: 128)
            try self.validate(self.roomIdentifier, name: "roomIdentifier", parent: name, min: 1)
            try self.validate(self.roomIdentifier, name: "roomIdentifier", parent: name, pattern: "^arn:aws:ivschat:[a-z0-9-]+:[0-9]+:room/[a-zA-Z0-9-]+$")
        }

        private enum CodingKeys: String, CodingKey {
            case attributes = "attributes"
            case eventName = "eventName"
            case roomIdentifier = "roomIdentifier"
        }
    }

    public struct SendEventResponse: AWSDecodableShape {
        /// An identifier generated by Amazon IVS Chat. This identifier must be used in subsequent operations for this message, such as DeleteMessage.
        public let id: String?

        @inlinable
        public init(id: String? = nil) {
            self.id = id
        }

        private enum CodingKeys: String, CodingKey {
            case id = "id"
        }
    }

    public struct ServiceQuotaExceededException: AWSErrorShape {
        public let limit: Int
        public let message: String
        public let resourceId: String
        public let resourceType: ResourceType

        @inlinable
        public init(limit: Int, message: String, resourceId: String, resourceType: ResourceType) {
            self.limit = limit
            self.message = message
            self.resourceId = resourceId
            self.resourceType = resourceType
        }

        private enum CodingKeys: String, CodingKey {
            case limit = "limit"
            case message = "message"
            case resourceId = "resourceId"
            case resourceType = "resourceType"
        }
    }

    public struct TagResourceRequest: AWSEncodableShape {
        /// The ARN of the resource to be tagged. The ARN must be URL-encoded.
        public let resourceArn: String
        /// Array of tags to be added or updated. Array of maps, each of the form string:string (key:value). See Best practices and strategies in Tagging Amazon Web Services Resources and Tag Editor for details, including restrictions that apply to tags and "Tag naming limits and requirements"; Amazon IVS Chat has no constraints beyond what is documented there.
        public let tags: [String: String]

        @inlinable
        public init(resourceArn: String, tags: [String: String]) {
            self.resourceArn = resourceArn
            self.tags = tags
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            var container = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.resourceArn, key: "resourceArn")
            try container.encode(self.tags, forKey: .tags)
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 128)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws:ivschat:[a-z0-9-]+:[0-9]+:[a-z-]/[a-zA-Z0-9-]+$")
            try self.tags.forEach {
                try validate($0.key, name: "tags.key", parent: name, max: 128)
                try validate($0.key, name: "tags.key", parent: name, min: 1)
                try validate($0.value, name: "tags[\"\($0.key)\"]", parent: name, max: 256)
            }
            try self.validate(self.tags, name: "tags", parent: name, max: 50)
        }

        private enum CodingKeys: String, CodingKey {
            case tags = "tags"
        }
    }

    public struct TagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct ThrottlingException: AWSErrorShape {
        public let limit: Int
        public let message: String
        public let resourceId: String
        public let resourceType: ResourceType

        @inlinable
        public init(limit: Int, message: String, resourceId: String, resourceType: ResourceType) {
            self.limit = limit
            self.message = message
            self.resourceId = resourceId
            self.resourceType = resourceType
        }

        private enum CodingKeys: String, CodingKey {
            case limit = "limit"
            case message = "message"
            case resourceId = "resourceId"
            case resourceType = "resourceType"
        }
    }

    public struct UntagResourceRequest: AWSEncodableShape {
        /// The ARN of the resource to be untagged. The ARN must be URL-encoded.
        public let resourceArn: String
        /// Array of tags to be removed. Array of maps, each of the form string:string (key:value). See Best practices and strategies in Tagging Amazon Web Services Resources and Tag Editor for details, including restrictions that apply to tags and "Tag naming limits and requirements"; Amazon IVS Chat has no constraints beyond what is documented there.
        public let tagKeys: [String]

        @inlinable
        public init(resourceArn: String, tagKeys: [String]) {
            self.resourceArn = resourceArn
            self.tagKeys = tagKeys
        }

        public func encode(to encoder: Encoder) throws {
            let request = encoder.userInfo[.awsRequest]! as! RequestEncodingContainer
            _ = encoder.container(keyedBy: CodingKeys.self)
            request.encodePath(self.resourceArn, key: "resourceArn")
            request.encodeQuery(self.tagKeys, key: "tagKeys")
        }

        public func validate(name: String) throws {
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, max: 128)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, min: 1)
            try self.validate(self.resourceArn, name: "resourceArn", parent: name, pattern: "^arn:aws:ivschat:[a-z0-9-]+:[0-9]+:[a-z-]/[a-zA-Z0-9-]+$")
            try self.tagKeys.forEach {
                try validate($0, name: "tagKeys[]", parent: name, max: 128)
                try validate($0, name: "tagKeys[]", parent: name, min: 1)
            }
            try self.validate(self.tagKeys, name: "tagKeys", parent: name, max: 50)
        }

        private enum CodingKeys: CodingKey {}
    }

    public struct UntagResourceResponse: AWSDecodableShape {
        public init() {}
    }

    public struct UpdateLoggingConfigurationRequest: AWSEncodableShape {
        /// A complex type that contains a destination configuration for where chat content will be logged. There can be only one type of destination (cloudWatchLogs, firehose, or s3) in a destinationConfiguration.
        public let destinationConfiguration: DestinationConfiguration?
        /// Identifier of the logging configuration to be updated.
        public let identifier: String
        /// Logging-configuration name. The value does not need to be unique.
        public let name: String?

        @inlinable
        public init(destinationConfiguration: DestinationConfiguration? = nil, identifier: String, name: String? = nil) {
            self.destinationConfiguration = destinationConfiguration
            self.identifier = identifier
            self.name = name
        }

        public func validate(name: String) throws {
            try self.destinationConfiguration?.validate(name: "\(name).destinationConfiguration")
            try self.validate(self.identifier, name: "identifier", parent: name, max: 128)
            try self.validate(self.identifier, name: "identifier", parent: name, min: 1)
            try self.validate(self.identifier, name: "identifier", parent: name, pattern: "^arn:aws:ivschat:[a-z0-9-]+:[0-9]+:logging-configuration/[a-zA-Z0-9-]+$")
            try self.validate(self.name, name: "name", parent: name, max: 128)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[a-zA-Z0-9-_]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case destinationConfiguration = "destinationConfiguration"
            case identifier = "identifier"
            case name = "name"
        }
    }

    public struct UpdateLoggingConfigurationResponse: AWSDecodableShape {
        /// Logging-configuration ARN, from the request (if identifier was an ARN).
        public let arn: String?
        /// Time when the logging configuration was created. This is an ISO 8601 timestamp; note that this is returned as a string.
        @OptionalCustomCoding<ISO8601DateCoder>
        public var createTime: Date?
        /// A complex type that contains a destination configuration for where chat content will be logged, from the request. There is only one type of destination (cloudWatchLogs, firehose, or s3) in a destinationConfiguration.
        public let destinationConfiguration: DestinationConfiguration?
        /// Logging-configuration ID, generated by the system. This is a relative identifier, the part of the ARN that uniquely identifies the room.
        public let id: String?
        /// Logging-configuration name, from the request (if specified).
        public let name: String?
        /// The state of the logging configuration. When the state is ACTIVE, the configuration is ready to log chat content.
        public let state: UpdateLoggingConfigurationState?
        /// Tags attached to the resource. Array of maps, each of the form string:string (key:value).
        public let tags: [String: String]?
        /// Time of the logging configuration’s last update. This is an ISO 8601 timestamp; note that this is returned as a string.
        @OptionalCustomCoding<ISO8601DateCoder>
        public var updateTime: Date?

        @inlinable
        public init(arn: String? = nil, createTime: Date? = nil, destinationConfiguration: DestinationConfiguration? = nil, id: String? = nil, name: String? = nil, state: UpdateLoggingConfigurationState? = nil, tags: [String: String]? = nil, updateTime: Date? = nil) {
            self.arn = arn
            self.createTime = createTime
            self.destinationConfiguration = destinationConfiguration
            self.id = id
            self.name = name
            self.state = state
            self.tags = tags
            self.updateTime = updateTime
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case createTime = "createTime"
            case destinationConfiguration = "destinationConfiguration"
            case id = "id"
            case name = "name"
            case state = "state"
            case tags = "tags"
            case updateTime = "updateTime"
        }
    }

    public struct UpdateRoomRequest: AWSEncodableShape {
        /// Identifier of the room to be updated. Currently this must be an ARN.
        public let identifier: String
        /// Array of logging-configuration identifiers attached to the room.
        public let loggingConfigurationIdentifiers: [String]?
        /// The maximum number of characters in a single message. Messages are expected to be UTF-8 encoded and this limit applies specifically to rune/code-point count, not number of bytes. Default: 500.
        public let maximumMessageLength: Int?
        /// Maximum number of messages per second that can be sent to the room (by all clients). Default: 10.
        public let maximumMessageRatePerSecond: Int?
        /// Configuration information for optional review of messages. Specify an empty uri string to disassociate a message review handler from the specified room.
        public let messageReviewHandler: MessageReviewHandler?
        /// Room name. The value does not need to be unique.
        public let name: String?

        @inlinable
        public init(identifier: String, loggingConfigurationIdentifiers: [String]? = nil, maximumMessageLength: Int? = nil, maximumMessageRatePerSecond: Int? = nil, messageReviewHandler: MessageReviewHandler? = nil, name: String? = nil) {
            self.identifier = identifier
            self.loggingConfigurationIdentifiers = loggingConfigurationIdentifiers
            self.maximumMessageLength = maximumMessageLength
            self.maximumMessageRatePerSecond = maximumMessageRatePerSecond
            self.messageReviewHandler = messageReviewHandler
            self.name = name
        }

        public func validate(name: String) throws {
            try self.validate(self.identifier, name: "identifier", parent: name, max: 128)
            try self.validate(self.identifier, name: "identifier", parent: name, min: 1)
            try self.validate(self.identifier, name: "identifier", parent: name, pattern: "^arn:aws:ivschat:[a-z0-9-]+:[0-9]+:room/[a-zA-Z0-9-]+$")
            try self.loggingConfigurationIdentifiers?.forEach {
                try validate($0, name: "loggingConfigurationIdentifiers[]", parent: name, max: 128)
                try validate($0, name: "loggingConfigurationIdentifiers[]", parent: name, min: 1)
                try validate($0, name: "loggingConfigurationIdentifiers[]", parent: name, pattern: "^arn:aws:ivschat:[a-z0-9-]+:[0-9]+:logging-configuration/[a-zA-Z0-9-]+$")
            }
            try self.validate(self.loggingConfigurationIdentifiers, name: "loggingConfigurationIdentifiers", parent: name, max: 3)
            try self.validate(self.maximumMessageLength, name: "maximumMessageLength", parent: name, max: 500)
            try self.validate(self.maximumMessageLength, name: "maximumMessageLength", parent: name, min: 1)
            try self.validate(self.maximumMessageRatePerSecond, name: "maximumMessageRatePerSecond", parent: name, max: 100)
            try self.validate(self.maximumMessageRatePerSecond, name: "maximumMessageRatePerSecond", parent: name, min: 1)
            try self.messageReviewHandler?.validate(name: "\(name).messageReviewHandler")
            try self.validate(self.name, name: "name", parent: name, max: 128)
            try self.validate(self.name, name: "name", parent: name, pattern: "^[a-zA-Z0-9-_]*$")
        }

        private enum CodingKeys: String, CodingKey {
            case identifier = "identifier"
            case loggingConfigurationIdentifiers = "loggingConfigurationIdentifiers"
            case maximumMessageLength = "maximumMessageLength"
            case maximumMessageRatePerSecond = "maximumMessageRatePerSecond"
            case messageReviewHandler = "messageReviewHandler"
            case name = "name"
        }
    }

    public struct UpdateRoomResponse: AWSDecodableShape {
        /// Room ARN, from the request (if identifier was an ARN).
        public let arn: String?
        /// Time when the room was created. This is an ISO 8601 timestamp; note that this is returned as a string.
        @OptionalCustomCoding<ISO8601DateCoder>
        public var createTime: Date?
        /// Room ID, generated by the system. This is a relative identifier, the part of the ARN that uniquely identifies the room.
        public let id: String?
        /// Array of logging configurations attached to the room, from the request (if specified).
        public let loggingConfigurationIdentifiers: [String]?
        /// Maximum number of characters in a single message, from the request (if specified).
        public let maximumMessageLength: Int?
        /// Maximum number of messages per second that can be sent to the room (by all clients), from the request (if specified).
        public let maximumMessageRatePerSecond: Int?
        /// Configuration information for optional review of messages.
        public let messageReviewHandler: MessageReviewHandler?
        /// Room name, from the request (if specified).
        public let name: String?
        /// Tags attached to the resource. Array of maps, each of the form string:string (key:value).
        public let tags: [String: String]?
        /// Time of the room’s last update. This is an ISO 8601 timestamp; note that this is returned as a string.
        @OptionalCustomCoding<ISO8601DateCoder>
        public var updateTime: Date?

        @inlinable
        public init(arn: String? = nil, createTime: Date? = nil, id: String? = nil, loggingConfigurationIdentifiers: [String]? = nil, maximumMessageLength: Int? = nil, maximumMessageRatePerSecond: Int? = nil, messageReviewHandler: MessageReviewHandler? = nil, name: String? = nil, tags: [String: String]? = nil, updateTime: Date? = nil) {
            self.arn = arn
            self.createTime = createTime
            self.id = id
            self.loggingConfigurationIdentifiers = loggingConfigurationIdentifiers
            self.maximumMessageLength = maximumMessageLength
            self.maximumMessageRatePerSecond = maximumMessageRatePerSecond
            self.messageReviewHandler = messageReviewHandler
            self.name = name
            self.tags = tags
            self.updateTime = updateTime
        }

        private enum CodingKeys: String, CodingKey {
            case arn = "arn"
            case createTime = "createTime"
            case id = "id"
            case loggingConfigurationIdentifiers = "loggingConfigurationIdentifiers"
            case maximumMessageLength = "maximumMessageLength"
            case maximumMessageRatePerSecond = "maximumMessageRatePerSecond"
            case messageReviewHandler = "messageReviewHandler"
            case name = "name"
            case tags = "tags"
            case updateTime = "updateTime"
        }
    }

    public struct ValidationException: AWSErrorShape {
        public let fieldList: [ValidationExceptionField]?
        public let message: String
        public let reason: ValidationExceptionReason

        @inlinable
        public init(fieldList: [ValidationExceptionField]? = nil, message: String, reason: ValidationExceptionReason) {
            self.fieldList = fieldList
            self.message = message
            self.reason = reason
        }

        private enum CodingKeys: String, CodingKey {
            case fieldList = "fieldList"
            case message = "message"
            case reason = "reason"
        }
    }

    public struct ValidationExceptionField: AWSDecodableShape {
        /// Explanation of the reason for the validation error.
        public let message: String
        /// Name of the field which failed validation.
        public let name: String

        @inlinable
        public init(message: String, name: String) {
            self.message = message
            self.name = name
        }

        private enum CodingKeys: String, CodingKey {
            case message = "message"
            case name = "name"
        }
    }
}

// MARK: - Errors

/// Error enum for Ivschat
public struct IvschatErrorType: AWSErrorType {
    enum Code: String {
        case accessDeniedException = "AccessDeniedException"
        case conflictException = "ConflictException"
        case internalServerException = "InternalServerException"
        case pendingVerification = "PendingVerification"
        case resourceNotFoundException = "ResourceNotFoundException"
        case serviceQuotaExceededException = "ServiceQuotaExceededException"
        case throttlingException = "ThrottlingException"
        case validationException = "ValidationException"
    }

    private let error: Code
    public let context: AWSErrorContext?

    /// initialize Ivschat
    public init?(errorCode: String, context: AWSErrorContext) {
        guard let error = Code(rawValue: errorCode) else { return nil }
        self.error = error
        self.context = context
    }

    internal init(_ error: Code) {
        self.error = error
        self.context = nil
    }

    /// return error code string
    public var errorCode: String { self.error.rawValue }

    public static var accessDeniedException: Self { .init(.accessDeniedException) }
    public static var conflictException: Self { .init(.conflictException) }
    public static var internalServerException: Self { .init(.internalServerException) }
    public static var pendingVerification: Self { .init(.pendingVerification) }
    public static var resourceNotFoundException: Self { .init(.resourceNotFoundException) }
    public static var serviceQuotaExceededException: Self { .init(.serviceQuotaExceededException) }
    public static var throttlingException: Self { .init(.throttlingException) }
    public static var validationException: Self { .init(.validationException) }
}

extension IvschatErrorType: AWSServiceErrorType {
    public static let errorCodeMap: [String: AWSErrorShape.Type] = [
        "ConflictException": Ivschat.ConflictException.self,
        "ResourceNotFoundException": Ivschat.ResourceNotFoundException.self,
        "ServiceQuotaExceededException": Ivschat.ServiceQuotaExceededException.self,
        "ThrottlingException": Ivschat.ThrottlingException.self,
        "ValidationException": Ivschat.ValidationException.self
    ]
}

extension IvschatErrorType: Equatable {
    public static func == (lhs: IvschatErrorType, rhs: IvschatErrorType) -> Bool {
        lhs.error == rhs.error
    }
}

extension IvschatErrorType: CustomStringConvertible {
    public var description: String {
        return "\(self.error.rawValue): \(self.message ?? "")"
    }
}
